package com.xunfang.portal.controller;

import com.alipay.api.internal.util.AlipaySignature;
import com.xunfang.common.enumeration.OrderStatus;
import com.xunfang.common.enumeration.impl.BusinessCode;
import com.xunfang.common.exception.Assert;
import com.xunfang.portal.annotion.Idempotent;
import com.xunfang.portal.config.AlipayConfig;
import com.xunfang.portal.model.request.OrderRequest;
import com.xunfang.portal.model.request.PayRequest;
import com.xunfang.portal.model.vo.OrderVo;
import com.xunfang.portal.service.OrderService;
import com.xunfang.portal.utils.JwtUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/order")
@Tag(name = "订单模块")
@Slf4j
public class OrderController {

    @Autowired
    private OrderService orderService;

    @Autowired
    private JwtUtils jwtUtil;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 创建订单
     */
    @PostMapping("/createOrder")
    @Operation(summary = "创建订单")
//    @Idempotent  //使用幂等注解
    public ResponseEntity<String> createOrder(
            @RequestHeader(name = "Authorization", required = false)
        String token,
            @RequestBody OrderRequest request) {

        //获取uniqueCode和addressId
        String uniqueCode = request.getUniqueCode();
        Integer addressId = request.getAddressId();
        log.info("uniqueCode: {}, addressId: {}", uniqueCode, addressId);

//        // 判断Redis中唯一标识是否已经存在，如果存在则直接返回。键：唯一标识，值：1， 15秒后过期
//        Boolean ifAbsent = redisTemplate.opsForValue().setIfAbsent(uniqueCode, 1, Duration.ofSeconds(15));
//        //如果返回true，表示设置成功，如果返回false，表示已经提交过，返回错误
//        Assert.error(!ifAbsent, BusinessCode.REPEAT_COMMIT);

        //从token中获取userId
        Long userId = Long.valueOf(jwtUtil.getValue(token, "userId"));
        //调用业务层创建订单
        String orderNum = orderService.createOrder(userId, addressId);
        return ResponseEntity.ok("订单提交成功，订单号：" + orderNum);
    }

    /**
     * 查询订单
     */
    @GetMapping("/loadOrdersByStatus")
    @Operation(summary = "查询指定状态的订单")
    public ResponseEntity<List<OrderVo>> loadOrdersByStatus(
            @RequestHeader(name = "Authorization", required = false) String token, Integer status) {
        //从token中获取userId
        Long userId = Long.valueOf(jwtUtil.getValue(token, "userId"));
        //调用业务层查询订单
        List<OrderVo> orderVos = orderService.queryOrder(userId, status);
        return ResponseEntity.ok(orderVos);
    }

    /**
     * 支付接口
     *
     * @return 返回一个包含表单数据的HTML网页
     */
    @PostMapping("/pay")
    @Operation(summary = "支付接口")
    public ResponseEntity<String> pay(@RequestBody PayRequest request) {
        //调用业务层支会
        String form = orderService.pay(Long.valueOf(request.getOrderId()));
        return ResponseEntity.ok(form);
    }

    @Autowired
    private AlipayConfig alipayConfig;

    /**
     * 支付宝异步回调接口
     * http://内网穿透地址/order/notify
     */
    @SneakyThrows
    @PostMapping("/notify")
    public void aliPayNotify(HttpServletRequest request) {
        //获取所有请求参数，重新创建一个Map再封装一次数据
        Map<String, String> params = request.getParameterMap().entrySet().stream()
                .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue()[0]));
        // 验证签名
        String sign = params.get("sign");
        String contentV1 = AlipaySignature.getSignCheckContentV1(params);
        boolean rsa256CheckSignature = AlipaySignature.rsa256CheckContent(contentV1,
                sign, alipayConfig.getAlipayPublicKey(), "UTF-8");

        //表示支付成功
        if (rsa256CheckSignature && "TRADE_SUCCESS".equals(params.get("trade_status"))) {
            // 签名验证成功 并且 支付宝回调的状态是成功状态 TRADE_SUCCESS
            log.info("在{}，买家{}进行订单{}的付款，交易名称{}，付款金额{}", params.get("gmt_payment"), params.get("buyer_id"),
                    params.get("out_trade_no"), params.get("subject"), params.get("total_amount"));

            // 支付成功，修改数据库中该订单的状态，out_trade_no即订单ID
            String outTradeNo = params.get("out_trade_no");
            //更新订单状态为待发货
            orderService.updateOrderStatus(Long.valueOf(outTradeNo), OrderStatus.NO_SEND.getCode());

            log.info("订单{}支付成功，状态修改为待发货", outTradeNo);
        } else {
            log.error("支付宝支付失败");
        }
    }

}